﻿using System;
using System.IO;
using System.Net;
using LiveNet.Authentication;
using LiveNet.Configuration;

namespace LiveNet
{
    public abstract class LiveNetBase<TRequestCreator, TAuthenticationDetails>
        where TRequestCreator : IWebRequestCreator<TAuthenticationDetails>, new()
        where TAuthenticationDetails : LiveNetAuthenticationDetails
    {
        private readonly TAuthenticationDetails m_AuthenticationDetails;
        protected Uri m_RootPath;
        protected Uri m_InvitationPath;

        protected LiveNetBase(TAuthenticationDetails authenticationDetails, Uri rootPath)
        {
            if (authenticationDetails == null)
            {
                throw new ArgumentNullException("authenticationDetails");
            }

            m_AuthenticationDetails = authenticationDetails;
            m_RootPath = rootPath;
        }

        protected LiveNetBase(TAuthenticationDetails authenticationDetails)
        {
            if (authenticationDetails == null)
            {
                throw new ArgumentNullException("authenticationDetails");
            }

            m_AuthenticationDetails = authenticationDetails;
        }

        protected Uri RootPath
        {
            get { return m_RootPath; }
        }

        protected TAuthenticationDetails AuthenticationDetails
        {
            get { return m_AuthenticationDetails; }
        }

        protected bool IsValidRootPathUrl(Uri url)
        {
            return url.OriginalString.StartsWith(RootPath.OriginalString);
        }

        protected HttpWebRequest BuildRequest(Uri uri, string method)
        {
            if (string.IsNullOrEmpty(method))
            {
                throw new ArgumentNullException("method");
            }

            TRequestCreator a = new TRequestCreator();
            HttpWebRequest request = a.Create(uri, m_AuthenticationDetails);
            request.Method = method;
            
            return request;
        }

        protected static void CopyStream(Stream istream, Stream ostream)
        {
            byte[] buffer = new byte[2048];
            int bytes;
            while (0 < (bytes = istream.Read(buffer, 0, buffer.Length)))
            {
                ostream.Write(buffer, 0, bytes);
            }
        }
    }
}
